/*
 * Copyright 2025 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.beit.mybatis.demo.common.mapper.provider;

import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;

public class CustomConditionProvider extends MapperTemplate {

    public CustomConditionProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }

    public String selectByCustomCondition(MappedStatement ms) {
        Class<?> entityClass = getEntityClass(ms);
        // 将返回值修改为实体类型
        setResultType(ms, entityClass);
        StringBuilder sql = new StringBuilder("SELECT ");
        if (isCheckExampleEntityClass()) {
            sql.append(SqlHelper.exampleCheck(entityClass));
        }
        sql.append("<if test=\"distinct\">distinct</if>");
        // 支持查询指定列
        sql.append(SqlHelper.exampleSelectColumns(entityClass));
        sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
        // 增加多字段 IN 支持
        sql.append(exampleWhereClause());
        sql.append(SqlHelper.exampleOrderBy(entityClass));
        sql.append(SqlHelper.exampleForUpdate());
        return sql.toString();
    }

    public static String exampleWhereClause() {
        return """
                <if test="_parameter != null"><where>
                 ${@tk.mybatis.mapper.util.OGNL@andNotLogicDelete(_parameter)} <trim prefix="(" prefixOverrides="and |or " suffix=")">
                  <foreach collection="oredCriteria" item="criteria">
                    <if test="criteria.valid">
                      ${@tk.mybatis.mapper.util.OGNL@andOr(criteria)}      <trim prefix="(" prefixOverrides="and |or " suffix=")">
                        <foreach collection="criteria.criteria" item="criterion">
                          <choose>
                            <when test="criterion.noValue">
                              ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition}
                            </when>
                            <when test="criterion.singleValue">
                              ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition} #{criterion.value}
                            </when>
                            <when test="criterion.betweenValue">
                              ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                            </when>
                            <when test="criterion.listValue">
                              ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition}
                              <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                                #{listItem}
                              </foreach>
                            </when>
                            <when test="criterion.multiListValue">
                              ${@tk.mybatis.mapper.util.OGNL@andOr(criterion)} ${criterion.condition}
                              <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                                <foreach close=")" collection="criterion.secondValue" item="itemProperty" open="(" separator=",">
                                  #{listItem.${itemProperty}}
                                </foreach>
                              </foreach>
                            </when>
                          </choose>
                        </foreach>
                      </trim>
                    </if>
                  </foreach>
                 </trim>
                </where></if>
                """;
    }
}
